package com.csdware.devilsalarm;


import android.app.AlarmManager;
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Parcelable;
import android.os.PowerManager;
import android.provider.OpenableColumns;
import android.provider.Settings;
import android.text.Editable;
import android.text.TextWatcher;
import android.Manifest;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.csdware.devilsalarm.lib_FileSelect.FileSelectConstant;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;

public class MainActivity extends AppCompatActivity implements LocationListener {
    Application_Data applicationData;
    private int PreferredLocationManagerIndex = 0;
    private int TargetAlarmHour;
    private int TargetAlarmMinute;
    private AtomicLong CurrentLongitude;  // 由于没有原子浮点型变量，因此这个存储进去的值被乘上了1000000
    private AtomicLong CurrentLatitude;  // 由于没有原子浮点型变量，因此这个存储进去的值被乘上了1000000
    private EditText TargetLongitude;
    private EditText TargetLatitude;
    private EditText SafeZoneRadius;
    private EditText Extension;
    private EditText HijackDirectory;
    private EditText RetrieveTimeout;
    private EditText EncryptedFileAmount;
    private EditText RingtonePath;
    private View LocationUpdateIndicator;
    private final Handler PeriodicUpdateTimeLeftHandler = new Handler();
    private Runnable PeriodicUpdateTimeLeftFunction;
    private final int PeriodicUpdateTimeLeftInterval = 5000;
    public static final int REQUEST_CODE_READ_WRITE_PERMISSION_OLD = 1001;
    public static final int REQUEST_CODE_READ_WRITE_PERMISSION_NEW = 1002;
    public static final int REQUEST_CODE_LOCATION = 1003;
    public static final int REQUEST_CODE_INTEGRATED_FILE_CHOOSER = 1004;
    public static final int REQUEST_CODE_NATIVE_FILE_CHOOSER = 1005;
    public static final int REQUEST_START_ALARM_COUNTDOWN = 1006;
    public static final int REQUEST_SETTINGS = 1007;
    public static final int REQUEST_HELP = 1008;
    public static final int REQUEST_EXACT_ALARM = 1009;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // ----------------------Resources的重载必须要赶在被缓存之前----------------------
        SharedPreferences SharedPrefs = getSharedPreferences("data", MODE_PRIVATE);
        SharedPreferences.Editor SharedPrefsEditor = SharedPrefs.edit();
        Locale usLocale;
        switch (SharedPrefs.getInt("language", 0)) {
            case 0:
                usLocale = new Locale("en", "US");
                break;
            case 1:
                usLocale = new Locale("zh", "CN");
                break;
            default:
                usLocale = new Locale("en", "US");
                break;
        }
        Locale.setDefault(usLocale);
        Configuration config = new Configuration();
        config.locale = usLocale;
        getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
        applicationData = (Application_Data) getApplicationContext();
        applicationData.powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
        applicationData.wakeLock = applicationData.powerManager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.FULL_WAKE_LOCK, "MyApp::MyWakelockTag");
        AMapLocationClient.updatePrivacyAgree(getApplicationContext(), true);
        AMapLocationClient.updatePrivacyShow(getApplicationContext(), true, true);

        // ----------------------基本布局初始化----------------------
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        EdgeToEdge.enable(this);  // 使画面延伸到状态栏和导航栏，沉浸感更强
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);  // 强制开启深色模式并禁止主题跟随系统
        if (android.os.Build.VERSION.SDK_INT >= 30) {
            WindowInsetsController windowInsetsController = getWindow().getInsetsController();
            if (windowInsetsController != null) {
                windowInsetsController.hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
                windowInsetsController.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
            }
        }
        TextView HintRestTime = findViewById(R.id.hint_rest_time);
        PeriodicUpdateTimeLeftFunction = new Runnable() {
            @Override
            public void run() {
                RefreshHintRestTime(HintRestTime);
                PeriodicUpdateTimeLeftHandler.postDelayed(this, PeriodicUpdateTimeLeftInterval);
            }
        };
        CurrentLongitude = new AtomicLong(0);
        CurrentLatitude = new AtomicLong(0);

        // ----------------------小时设定器的初始化----------------------
        {
            TargetAlarmHour = SharedPrefs.getInt("TargetAlarmHour", 13);
            TargetAlarmMinute = SharedPrefs.getInt("TargetAlarmMinute", 14);
            TextView SetTimeHourPlus = findViewById(R.id.bt_time_hour_plus);
            TextView SetTimeHourDisplay = findViewById(R.id.dsp_time_hour_target);
            TextView SetTimeHourMinus = findViewById(R.id.bt_time_hour_minus);
            RefreshHintRestTime(HintRestTime);
            SetTimeHourPlus.setOnClickListener(view -> {
                TargetAlarmHour++;
                if (TargetAlarmHour > 23) TargetAlarmHour = 0;
                SharedPrefsEditor.putInt("TargetAlarmHour", TargetAlarmHour);
                SharedPrefsEditor.apply();
                SetTimeHourDisplay.setText(String.valueOf(TargetAlarmHour));
                RefreshHintRestTime(HintRestTime);
            });
            SetTimeHourDisplay.setText(String.valueOf(TargetAlarmHour));
            SetTimeHourMinus.setOnClickListener(view -> {
                TargetAlarmHour--;
                if (TargetAlarmHour < 0) TargetAlarmHour = 23;
                SharedPrefsEditor.putInt("TargetAlarmHour", TargetAlarmHour);
                SharedPrefsEditor.apply();
                SetTimeHourDisplay.setText(String.valueOf(TargetAlarmHour));
                RefreshHintRestTime(HintRestTime);
            });
        }

        // ----------------------分钟设定器的初始化----------------------
        {
            TextView SetTimeMinutePlus = findViewById(R.id.bt_time_minute_plus);
            TextView SetTimeMinuteDisplay = findViewById(R.id.dsp_time_minute_target);
            TextView SetTimeMinuteMinus = findViewById(R.id.bt_time_minute_minus);
            SetTimeMinutePlus.setOnClickListener(view -> {
                TargetAlarmMinute++;
                if (TargetAlarmMinute > 59) TargetAlarmMinute = 0;
                SharedPrefsEditor.putInt("TargetAlarmMinute", TargetAlarmMinute);
                SharedPrefsEditor.apply();
                SetTimeMinuteDisplay.setText(String.valueOf(TargetAlarmMinute));
                RefreshHintRestTime(HintRestTime);
            });
            SetTimeMinuteDisplay.setText(String.valueOf(TargetAlarmMinute));
            SetTimeMinuteMinus.setOnClickListener(view -> {
                TargetAlarmMinute--;
                if (TargetAlarmMinute < 0) TargetAlarmMinute = 59;
                SharedPrefsEditor.putInt("TargetAlarmMinute", TargetAlarmMinute);
                SharedPrefsEditor.apply();
                SetTimeMinuteDisplay.setText(String.valueOf(TargetAlarmMinute));
                RefreshHintRestTime(HintRestTime);
            });
        }

        // ----------------------文本框的初始化以及历史取值读取----------------------
        {
            TargetLongitude = findViewById(R.id.tb_target_longitude);
            String LastTargetLongitude = SharedPrefs.getString("LastTargetLongitude", "");
            if (!LastTargetLongitude.isEmpty()) TargetLongitude.setText(LastTargetLongitude);
            TargetLongitude.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                }

                @Override
                public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                }

                @Override
                public void afterTextChanged(Editable editable) {
                    SharedPrefsEditor.putString("LastTargetLongitude", editable.toString());
                    SharedPrefsEditor.apply();
                }
            });

            TargetLatitude = findViewById(R.id.tb_target_latitude);
            String LastTargetLatitude = SharedPrefs.getString("LastTargetLatitude", "");
            if (!LastTargetLatitude.isEmpty()) TargetLatitude.setText(LastTargetLatitude);
            TargetLatitude.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                }

                @Override
                public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                }

                @Override
                public void afterTextChanged(Editable editable) {
                    SharedPrefsEditor.putString("LastTargetLatitude", editable.toString());
                    SharedPrefsEditor.apply();
                }
            });

            SafeZoneRadius = findViewById(R.id.tb_safe_zone_radius);
            String LastSafeZoneRadius = SharedPrefs.getString("LastSafeZoneRadius", "20");
            if (!LastSafeZoneRadius.isEmpty()) SafeZoneRadius.setText(LastSafeZoneRadius);
            SafeZoneRadius.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                }

                @Override
                public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                }

                @Override
                public void afterTextChanged(Editable editable) {
                    SharedPrefsEditor.putString("LastSafeZoneRadius", editable.toString());
                    SharedPrefsEditor.apply();
                }
            });

            Extension = findViewById(R.id.tb_extension);
            String LastExtension = SharedPrefs.getString("LastExtension", ".jpg");
            if (!LastExtension.isEmpty()) Extension.setText(LastExtension);
            Extension.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                }

                @Override
                public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                }

                @Override
                public void afterTextChanged(Editable editable) {
                    SharedPrefsEditor.putString("LastExtension", editable.toString());
                    SharedPrefsEditor.apply();
                }
            });

            HijackDirectory = findViewById(R.id.tb_hijack_directory);
            String LastHijackDirectory = SharedPrefs.getString("LastHijackDirectory", "/storage/emulated/0/DCIM/Camera");
            if (!LastHijackDirectory.isEmpty()) HijackDirectory.setText(LastHijackDirectory);
            HijackDirectory.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                }

                @Override
                public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                }

                @Override
                public void afterTextChanged(Editable editable) {
                    SharedPrefsEditor.putString("LastHijackDirectory", editable.toString());
                    SharedPrefsEditor.apply();
                }
            });

            RetrieveTimeout = findViewById(R.id.tb_retrieve_timeout);
            String LastRetrieveTimeout = SharedPrefs.getString("LastRetrieveTimeout", "600");
            if (!LastRetrieveTimeout.isEmpty()) RetrieveTimeout.setText(LastRetrieveTimeout);
            RetrieveTimeout.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                }

                @Override
                public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                }

                @Override
                public void afterTextChanged(Editable editable) {
                    SharedPrefsEditor.putString("LastRetrieveTimeout", editable.toString());
                    SharedPrefsEditor.apply();
                }
            });

            EncryptedFileAmount = findViewById(R.id.tb_encrypted_file_amount);
            String LastEncryptedFileAmount = SharedPrefs.getString("LastEncryptedFileAmount", "5");
            if (!LastEncryptedFileAmount.isEmpty())
                EncryptedFileAmount.setText(LastEncryptedFileAmount);
            EncryptedFileAmount.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                }

                @Override
                public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                }

                @Override
                public void afterTextChanged(Editable editable) {
                    SharedPrefsEditor.putString("LastEncryptedFileAmount", editable.toString());
                    SharedPrefsEditor.apply();
                }
            });

            RingtonePath = findViewById(R.id.tb_ringtone_path);
            String LastRingtonePath = SharedPrefs.getString("LastRingtonePath", "[default]");
            if (!LastRingtonePath.isEmpty()) RingtonePath.setText(LastRingtonePath);
            RingtonePath.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                }

                @Override
                public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                }

                @Override
                public void afterTextChanged(Editable editable) {
                    SharedPrefsEditor.putString("LastRingtonePath", editable.toString());
                    SharedPrefsEditor.apply();
                }
            });
        }

        // ----------------------定位逻辑的初始化----------------------
        {
            applicationData.AndroidDefaultLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
            PreferredLocationManagerIndex = SharedPrefs.getInt("LocationChoice", 0);
            switch (PreferredLocationManagerIndex) {
                case 0:
                    try {
                        AMapLocationListener AmapLocationListener = amapLocation -> {
                            if (amapLocation != null) {
                                if (amapLocation.getErrorCode() == 0) {
                                    CurrentLatitude.set((long) (amapLocation.getLatitude() * 1000000));
                                    CurrentLongitude.set((long) (amapLocation.getLongitude() * 1000000));
                                    LocationUpdateIndicator.setBackgroundColor(Color.argb(255, 226, 60, 60));
                                    LocationUpdateIndicator.postDelayed(() -> LocationUpdateIndicator.setBackgroundColor(Color.argb(255, 128, 4, 4)), 100);
                                } else {
                                    Log.e("AmapError", "location Error, ErrCode:" + amapLocation.getErrorCode() + ", errInfo:" + amapLocation.getErrorInfo());
                                }
                            }
                        };
                        applicationData.AmapLocationManager = new AMapLocationClient(getApplicationContext());
                        applicationData.AmapLocationManager.setLocationListener(AmapLocationListener);
                        AMapLocationClientOption mLocationOption = new AMapLocationClientOption();
                        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
                        mLocationOption.setInterval(2000);
                        mLocationOption.setLocationCacheEnable(true);
                        applicationData.AmapLocationManager.setLocationOption(mLocationOption);
                        applicationData.AmapLocationManager.startLocation();
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                    break;
                case 1:
                    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                            applicationData.AndroidDefaultLocationManager.requestLocationUpdates(LocationManager.FUSED_PROVIDER, 0, 0, MainActivity.this);
                        } else {
                            applicationData.AndroidDefaultLocationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, MainActivity.this);
                        }
                    }
                    break;
            }
            TextView ButtonFillCurrentCoordinate = findViewById(R.id.bt_fill_current_coordinate);
            LocationUpdateIndicator = findViewById(R.id.dsp_location_update_indicator);
            ButtonFillCurrentCoordinate.setOnClickListener(view -> {
                Toast.makeText(getApplicationContext(), R.string.restart_if_location_obtain_failed, Toast.LENGTH_SHORT).show();
                if (CurrentLongitude.get() == 0 || CurrentLatitude.get() == 0) {
                    Toast.makeText(getApplicationContext(), R.string.error_unable_to_fetch_location, Toast.LENGTH_SHORT).show();
                } else {
                    TargetLongitude.setText(String.valueOf((float) CurrentLongitude.get() / 1000000));
                    TargetLatitude.setText(String.valueOf((float) CurrentLatitude.get() / 1000000));
                }
            });
        }

        // ----------------------其余按钮逻辑的初始化----------------------
        {
            TextView ButtonSwitchLang = findViewById(R.id.bt_switch_lang);
            ButtonSwitchLang.setOnClickListener(view -> {
                if (SharedPrefs.getInt("language", 0) == 0) {
                    SharedPrefsEditor.putInt("language", 1);
                    SharedPrefsEditor.apply();
                    Toast.makeText(getApplicationContext(), "重新打开软件以应用语言更改", Toast.LENGTH_SHORT).show();
                } else {
                    SharedPrefsEditor.putInt("language", 0);
                    SharedPrefsEditor.apply();
                    Toast.makeText(getApplicationContext(), "Restart app to apply language modification", Toast.LENGTH_SHORT).show();
                }
            });
            TextView ButtonBrowseHijackPath = findViewById(R.id.bt_browse_hijack_path);
            ButtonBrowseHijackPath.setOnClickListener(view -> {
                Intent intent = new Intent();
                intent.setClass(getApplicationContext(), Activity_FileSelect.class);
                intent.putExtra(FileSelectConstant.SELECTOR_REQUEST_CODE_KEY, FileSelectConstant.SELECTOR_MODE_FOLDER);
                intent.putExtra(FileSelectConstant.SELECTOR_IS_MULTIPLE, false);
                startActivityForResult(intent, REQUEST_CODE_INTEGRATED_FILE_CHOOSER);
            });
            TextView ButtonBrowseRingtonePath = findViewById(R.id.bt_browse_ringtone_path);
            ButtonBrowseRingtonePath.setOnClickListener(view -> new Func_OpenWithExternal(MainActivity.this).openAssignFolder(REQUEST_CODE_NATIVE_FILE_CHOOSER));
            TextView ButtonStartAlarmCountdown = findViewById(R.id.bt_start_alarm_countdown);
            ButtonStartAlarmCountdown.setOnClickListener(view -> {
                CheckParameterThenWriteToApplicationData(false);
                Intent intent = new Intent();
                intent.setClass(getApplicationContext(), Activity_AlarmCountdown.class);
                startActivityForResult(intent, REQUEST_START_ALARM_COUNTDOWN);
            });
            TextView ButtonTestStartAlarmCountdown = findViewById(R.id.bt_test);
            ButtonTestStartAlarmCountdown.setOnClickListener(view -> {
                CheckParameterThenWriteToApplicationData(true);
                Intent intent = new Intent();
                intent.setClass(getApplicationContext(), Activity_AlarmCountdown.class);
                startActivityForResult(intent, REQUEST_START_ALARM_COUNTDOWN);
            });
            TextView ButtonCredits = findViewById(R.id.bt_credits);
            ButtonCredits.setOnClickListener(view -> {
                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                TextView textView = new TextView(MainActivity.this);
                textView.setText(R.string.credits_text);
                textView.setPadding(16, 16, 16, 16); // 设置内边距
                textView.setTextSize(13); // 设置字体大小
                textView.setLayoutParams(new LinearLayout.LayoutParams(
                        LinearLayout.LayoutParams.MATCH_PARENT,
                        LinearLayout.LayoutParams.WRAP_CONTENT));
                textView.setMovementMethod(new ScrollingMovementMethod()); // 允许滚动
                builder.setView(textView);
                AlertDialog dialog = builder.create();
                dialog.show();
            });
            TextView Button_Settings = findViewById(R.id.bt_settings);
            Button_Settings.setOnClickListener(view -> startActivityForResult(new Intent(MainActivity.this, Activity_Settings.class), REQUEST_SETTINGS));
            TextView ButtonHelp = findViewById(R.id.bt_help);
            ButtonHelp.setOnClickListener(view -> {
                CheckParameterThenWriteToApplicationData(true);
                startActivityForResult(new Intent(MainActivity.this, Activity_RedemptionMiniGame.class), REQUEST_HELP);
            });
        }
        new Handler(Looper.getMainLooper()).postDelayed(this::CheckPermission, 1500);
    }

    private void CheckParameterThenWriteToApplicationData(boolean PerformTest) {
        float C_TargetLongitude;
        try {
            C_TargetLongitude = Float.parseFloat(TargetLongitude.getText().toString());
        } catch (NumberFormatException e) {
            Toast.makeText(getApplicationContext(), getString(R.string.invalid_longitude), Toast.LENGTH_SHORT).show();
            return;
        }

        float C_TargetLatitude;
        try {
            C_TargetLatitude = Float.parseFloat(TargetLatitude.getText().toString());
        } catch (NumberFormatException e) {
            Toast.makeText(getApplicationContext(), getString(R.string.invalid_latitude), Toast.LENGTH_SHORT).show();
            return;
        }

        int C_SafeZoneRadius;
        try {
            C_SafeZoneRadius = Integer.parseInt(SafeZoneRadius.getText().toString());
            if (C_SafeZoneRadius < 0) {
                Toast.makeText(getApplicationContext(), getString(R.string.invalid_safe_zone_radius), Toast.LENGTH_SHORT).show();
                return;
            }
        } catch (NumberFormatException e) {
            Toast.makeText(getApplicationContext(), getString(R.string.invalid_safe_zone_radius), Toast.LENGTH_SHORT).show();
            return;
        }

        String C_Extension;
        if (Extension.getText().toString().startsWith(".")) {
            C_Extension = Extension.getText().toString();
        } else {
            Toast.makeText(getApplicationContext(), getString(R.string.invalid_extension_format), Toast.LENGTH_SHORT).show();
            return;
        }

        String C_HijackDirectory;
        File directory = new File(HijackDirectory.getText().toString());
        if (directory.exists() && directory.isDirectory()) {
            C_HijackDirectory = HijackDirectory.getText().toString();
        } else {
            Toast.makeText(getApplicationContext(), getString(R.string.hijack_directory_does_not_exist), Toast.LENGTH_SHORT).show();
            return;
        }

        int C_RetrieveTimeout;
        try {
            C_RetrieveTimeout = Integer.parseInt(RetrieveTimeout.getText().toString());
            if (C_RetrieveTimeout < 0) {
                Toast.makeText(getApplicationContext(), getString(R.string.invalid_retrieve_timeout), Toast.LENGTH_SHORT).show();
                return;
            }
        } catch (NumberFormatException e) {
            Toast.makeText(getApplicationContext(), getString(R.string.invalid_retrieve_timeout), Toast.LENGTH_SHORT).show();
            return;
        }

        int C_EncryptedFileAmount;
        try {
            C_EncryptedFileAmount = Integer.parseInt(EncryptedFileAmount.getText().toString());
            if (C_EncryptedFileAmount < 0) {
                Toast.makeText(getApplicationContext(), getString(R.string.invalid_encrypted_file_timeout), Toast.LENGTH_SHORT).show();
                return;
            }
        } catch (NumberFormatException e) {
            Toast.makeText(getApplicationContext(), getString(R.string.invalid_encrypted_file_timeout), Toast.LENGTH_SHORT).show();
            return;
        }

        String C_RingtonePath;
        String RingtonePathStr = RingtonePath.getText().toString();
        File ringtone_path = new File(RingtonePathStr);
        if (ringtone_path.exists() && ringtone_path.isFile()) {
            if (RingtonePathStr.endsWith(".mp3") || RingtonePathStr.endsWith(".wav") || RingtonePathStr.endsWith(".flac") || RingtonePathStr.endsWith(".aac"))
                C_RingtonePath = RingtonePathStr;
            else {
                Toast.makeText(getApplicationContext(), getString(R.string.not_a_supported_audio_file), Toast.LENGTH_SHORT).show();
                return;
            }
        } else {
            if (RingtonePathStr.equals("[default]")) {
                C_RingtonePath = RingtonePathStr;
            } else {
                Toast.makeText(getApplicationContext(), getString(R.string.ringtone_does_not_exist), Toast.LENGTH_SHORT).show();
                return;
            }
        }

        applicationData.PerformTest = PerformTest;
        applicationData.TargetAlarmHour = TargetAlarmHour;
        applicationData.TargetAlarmMinute = TargetAlarmMinute;
        applicationData.TargetLongitude = C_TargetLongitude;
        applicationData.TargetLatitude = C_TargetLatitude;
        applicationData.SafeZoneRadius = C_SafeZoneRadius;
        applicationData.Extension = C_Extension;
        applicationData.HijackDirectory = C_HijackDirectory;
        applicationData.RetrieveTimeout = C_RetrieveTimeout;
        applicationData.EncryptedFileAmount = C_EncryptedFileAmount;
        applicationData.RingtonePath = C_RingtonePath;
    }

    private void RefreshHintRestTime(TextView ModifyTarget) {
        int TotalMinutesLeft = getAlarmEtaMinutesLeft();
        int hourLeft = TotalMinutesLeft / 60;
        int minuteLeft = TotalMinutesLeft % 60;
        if (TotalMinutesLeft == 0)
            ModifyTarget.setText(String.format(getString(R.string.hint_rest_time), hourLeft, minuteLeft, getString(R.string.immediately)));
        else
            ModifyTarget.setText(String.format(getString(R.string.hint_rest_time), hourLeft, minuteLeft, ""));
    }

    private int getAlarmEtaMinutesLeft() {  // 计算当前时间与闹钟设定时间之间差了多久，也就是还有多久启动闹钟
        Calendar calendar = Calendar.getInstance();
        int NowHour = calendar.get(Calendar.HOUR_OF_DAY);
        int NowMinute = calendar.get(Calendar.MINUTE);
        int TotalMinutesLeft;
        if (TargetAlarmHour * 60 + TargetAlarmMinute >= NowHour * 60 + NowMinute) {  // 今天
            TotalMinutesLeft = (TargetAlarmHour * 60 + TargetAlarmMinute) - (NowHour * 60 + NowMinute);
        } else { // 明天
            TotalMinutesLeft = 24 * 60 - ((NowHour * 60 + NowMinute) - (TargetAlarmHour * 60 + TargetAlarmMinute));
        }
        return TotalMinutesLeft;
    }

    private String ParseUriFile(Intent intent) {
        Bundle extras = intent.getExtras();
        if (extras != null) {
            Object streamObject = extras.get(Intent.EXTRA_STREAM);
            if (streamObject instanceof ArrayList<?>) { // *****多文件的处理*****
                StringBuilder filePath_all = new StringBuilder();
                ArrayList<Parcelable> uris = (ArrayList<Parcelable>) streamObject;
                for (Parcelable uri : uris) {
                    if (uri instanceof Uri) {
                        // 处理每个 URI，这里你可以进行你需要的操作
                        String filePath_individual = Func_TryUriConvert.Convert((Uri) uri, MainActivity.this);
                        if (Objects.equals(filePath_individual, "")) {
                            filePath_individual = copyUriToFile((Uri) uri);
                        }
                        if (Objects.equals(filePath_all.toString(), "")) {
                            filePath_all = new StringBuilder(filePath_individual);
                        } else {
                            filePath_all.append("-//-").append(filePath_individual);
                        }
                    }
                }
                return filePath_all.toString();
            } else { // *****单文件的处理*****
                Uri uri = extras.getParcelable(Intent.EXTRA_STREAM);
                if (uri == null) {
                    Uri uri2 = intent.getData();
                    if (uri2 != null) {
                        String filePath = Func_TryUriConvert.Convert(uri2, MainActivity.this);
                        if (Objects.equals(filePath, "")) {
                            filePath = copyUriToFile(uri2);
                        }
                        return filePath;
                    }
                } else {
                    String filePath = Func_TryUriConvert.Convert(uri, MainActivity.this);
                    if (Objects.equals(filePath, "")) {
                        filePath = copyUriToFile(uri);
                    }
                    return filePath;
                }
            }
        } else {
            Uri uri = intent.getData();
            if (uri != null) {
                String filePath = Func_TryUriConvert.Convert(uri, MainActivity.this);
                if (Objects.equals(filePath, "")) {
                    filePath = copyUriToFile(uri);
                }
                return filePath;
            }
        }
        return "";
    }

    private String copyUriToFile(Uri uri) {
        try {
            InputStream inputStream = MainActivity.this.getContentResolver().openInputStream(uri);
            if (inputStream != null) {
                String absolutePath = getFilesDir().getAbsolutePath();
                File file = new File(absolutePath, getFileNameFromUri(uri));
                FileOutputStream outputStream = new FileOutputStream(file);
                byte[] buffer = new byte[1024];
                int length;
                while ((length = inputStream.read(buffer)) > 0) {
                    outputStream.write(buffer, 0, length);
                }
                inputStream.close();
                outputStream.close();
                Toast.makeText(MainActivity.this, "File Cached to" + getFilesDir().getAbsolutePath(), Toast.LENGTH_LONG).show();
                return file.getAbsolutePath();
            }
        } catch (IOException ignored) {
        }
        return "";
    }

    private String getFileNameFromUri(Uri uri) {
        ContentResolver contentResolver = MainActivity.this.getContentResolver();
        String fileName = null;
        // 使用 ContentResolver 查询文件名
        try (Cursor cursor = contentResolver.query(uri, null, null, null, null)) {
            if (cursor != null && cursor.moveToFirst()) {
                int displayNameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
                fileName = cursor.getString(displayNameIndex);
            }
        }
        return fileName;
    }

    private int CheckPermissionStep = 0;

    private void CheckPermission() {
        CheckPermissionStep++;
        switch (CheckPermissionStep) {
            case 1:
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
                    Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
                    intent.setData(Uri.parse("package:" + getPackageName()));
                    startActivityForResult(intent, REQUEST_CODE_READ_WRITE_PERMISSION_OLD);
                } else {
                    CheckPermission();
                }
                break;
            case 2:
                if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(MainActivity.this, new String[]{
                            Manifest.permission.WRITE_EXTERNAL_STORAGE,
                            Manifest.permission.READ_EXTERNAL_STORAGE
                    }, REQUEST_CODE_READ_WRITE_PERMISSION_NEW);
                } else {
                    CheckPermission();
                }
                break;
            case 3:
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
                    if (alarmManager.canScheduleExactAlarms()) {
                        CheckPermission();
                    } else {
                        Intent intent = new Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM);
                        intent.setData(Uri.parse("package:" + getPackageName()));
                        startActivityForResult(intent, REQUEST_EXACT_ALARM);
                    }
                } else {
                    CheckPermission();
                }
                break;
            case 4:
                if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 100);
                } else {
                    CheckPermission();
                }
                break;
            default:
                CheckPermissionStep = 0;
                break;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CODE_READ_WRITE_PERMISSION_NEW) {
            new Handler(Looper.getMainLooper()).postDelayed(this::CheckPermission, 500);
        } else if (requestCode == REQUEST_CODE_LOCATION) {
            new Handler(Looper.getMainLooper()).postDelayed(this::CheckPermission, 500);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_READ_WRITE_PERMISSION_OLD) {
            new Handler(Looper.getMainLooper()).postDelayed(this::CheckPermission, 500);
        } else if (requestCode == REQUEST_CODE_INTEGRATED_FILE_CHOOSER && resultCode == RESULT_OK) {
            HijackDirectory.setText(String.join("-//-", Objects.requireNonNull(data.getStringArrayListExtra(FileSelectConstant.SELECTOR_BUNDLE_PATHS))));
        } else if (requestCode == REQUEST_CODE_NATIVE_FILE_CHOOSER && resultCode == RESULT_OK) {
            String fp = ParseUriFile(data);
            if (!fp.isEmpty()) {
                RingtonePath.setText(fp);
            }
        } else if (requestCode == REQUEST_EXACT_ALARM) {
            new Handler(Looper.getMainLooper()).postDelayed(this::CheckPermission, 500);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        PeriodicUpdateTimeLeftHandler.removeCallbacks(PeriodicUpdateTimeLeftFunction);  // 如果因为某些bug在任务队列里添加了多个并行的延时任务，removeCallbacks也能将它们一次全部清除
        switch (PreferredLocationManagerIndex) {
            case 0:
                applicationData.AmapLocationManager.stopLocation();
            case 1:
                applicationData.AndroidDefaultLocationManager.removeUpdates(this);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        switch (PreferredLocationManagerIndex) {
            case 0:
                applicationData.AmapLocationManager.startLocation();
                break;
            case 1:
                if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                        applicationData.AndroidDefaultLocationManager.requestLocationUpdates(LocationManager.FUSED_PROVIDER, 0, 0, MainActivity.this);
                    } else {
                        applicationData.AndroidDefaultLocationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, MainActivity.this);
                    }
                }
                break;
        }
        PeriodicUpdateTimeLeftHandler.postDelayed(PeriodicUpdateTimeLeftFunction, 100);
    }

    @Override
    public void onLocationChanged(@NonNull Location location) {
        CurrentLatitude.set((long) (location.getLatitude() * 1000000));
        CurrentLongitude.set((long) (location.getLongitude() * 1000000));
        LocationUpdateIndicator.setBackgroundColor(Color.argb(255, 226, 60, 60));
        LocationUpdateIndicator.postDelayed(() -> LocationUpdateIndicator.setBackgroundColor(Color.argb(255, 128, 4, 4)), 100);
    }
}